<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #app {
            padding: 10px;
        }

        .input-box {
            margin: 10px;
            display: flex;
            align-items: center;
        }

        .input-box input {
            flex: 1;
            height: 30px;
            border: 1px solid #ccc;
            border: none;
            padding-left: 20px;
            border-radius: 5px;
            background-color: gainsboro;
        }

        .input-box span {
            text-align: center;
            color: lightseagreen;
            width: 60px;
        }

        .list {
            margin: 10px;
        }

        .list .task {
            margin: 20px 0;
            display: flex;
            justify-content: space-between;
            padding: 15px;
            background-color: red;
            color: white;
            font-size: 14px;
        }

        .list .task.finished {
            background-color: lightseagreen;
        }

        .empty {
            text-align: center;
            margin: 50px 0;
            color: red;
        }

        .box {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
            font-size: 14px;
            padding: 10px;
            box-sizing: border-box;
        }

        .box div {
            height: 15px;
            width: 25%;
            text-align: center;
            line-height: 15px;
            color: white;
            background-color: lightseagreen;
            padding: 10px;
            border-radius: 10px;
        }

        .box div:nth-child(3) {
            background-color: red;
        }

        #app>span {
            font-weight: 800;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="input-box">
            <input type="text" placeholder="输入任务名称" v-model="inputText">
            <span @click="add">添加</span>
        </div>
        <div class="box">
            <div>全部任务({{tasklist.length}})</div>
            <div>已完成({{finishedCount}})</div>
            <div>未完成({{unfinishedCount}})</div>
        </div>
        <span>任务列表</span>
        <div class="list">
            <div :class="{ task: true, finished: item.status }" v-for="(item,index) in tasklist" :key="index">
                <input type="checkbox" @click="changeStatus(item)">
                <div>{{item.id}}</div>
                <div class="name">{{item.name}}</div>
                <span @click="del(index)">删除</span>
            </div>
            <div class="empty" v-show="tasklist.length == 0">任务列表空空如也!</div>
        </div>
    </div>
    <script src="./vue-2.5.21.js"></script>
    <script>
        var v = new Vue({
            el: '#app',
            data: {
                inputText: '',
                tasklist: [
                ]
            },
            methods: {
                add() { //添加任务
                    if (this.inputText) {   //判断输入框中有内容的时候才能输入
                        //构造一个任务对象
                        var obj = { id: this.tasklist.length + 1, name: this.inputText, status: false };
                        //将任务对象 添加到任务列表中
                        this.tasklist.push(obj);
                        //清空输入框
                        this.inputText = '';
                    }
                },
                changeStatus(item) {
                    item.status = !item.status;
                },
                del(index) {
                    this.tasklist.splice(index, 1)
                },
                // finishedCount(){
                //     this.tasklist.filter((item) => {
                //         console.log('执行了');
                //         return item.status
                //     }).length
                // },
                // unfinishedCount(){
                //     return this.tasklist.length - this.finishedCount
                // }
            },
            /* 
                定义计算属性,计算属性定义时像函数,使用时像变量
                computed内的计算属性会缓存计算的结果,日说计算属性内所以来的数据没有发生改变,则计算属性不会重新计算,只会得到一个上一次缓存的结果
             */
            // computed: {
            //     finishedCount() {
            //         return this.tasklist.filter((item) => {
            //             return item.status
            //         }).length
            //     },
            //     unfinishedCount() {
            //         return this.tasklist.length - this.finishedCount
            //     }
            // },
            watch: {
                /*
                    定义数据的监听,可以监听到数据的改变,当被监听的数据发生改变时,会执行对应的函数 
                    写法一:函数的形式,可以监听到数据本身的改变,无法监听到内部数据属性的改变
                 */
                // tasklist() {
                //     this.finishedCount= this.tasklist.filter((item)=>{
                //             return item.status
                //         }).length
                //     this.unfinishedCount=this.tasklist.length-this.finishedCount
                // }
                /*
                    写法二:对象的形式+深度监听,可以监听到内部数据属性的改变 
                 */
                    tasklist: {
                        handler() { //这个位置的函数名必须是handler
                            this.finishedCount = this.tasklist.filter((item) => {
                                return item.status
                            }).length;
                            this.unfinishedCount=this.tasklist.length-this.finishedCount
                        },
                        deep: true,    //开启深度监听
                    }
                }
        })
        /*
            methods用来定义普通方法
                1.同一个方法调用多次,则执行多次,每次重新渲染时都会执行
                2.只支持函数的写法
            
            computed用来定义计算属性
                1.同一个计算属性使用多次,只有第一次会计算,后面多次重复使用不会重新计算(会将第一次计算的结果缓存起来)
                2.只有当内部所依赖的数据发生改变时才会重新计算
                3.计算属性内部不支持异步(不能写异步代码)
                4.支持函数的写法,对象的写法(set,get)
            
            watch用来监听的数据本身发生改变时,才会执行对应的回调函数
                1.只有当坚挺的数据本身发生改变的时候,才会执行对应的回调函数
                2.内部支持异步
                3.支持函数的写法,对象的写法(深度监听)
         */
    </script>
</body>

</html>